package service

import (
	"oa-system/internal/api/request"
	"oa-system/internal/model"
	"oa-system/internal/repository"
	"oa-system/pkg/errors"
)

type MenuService interface {
	GetAllMenus(page, pageSize int) ([]model.Menu, int64, error)
	GetMenuByID(id uint) (*model.Menu, error)
	CreateMenu(req *request.CreateMenuRequest) (*model.Menu, error)
	UpdateMenu(id uint, req *request.UpdateMenuRequest) (*model.Menu, error)
	DeleteMenu(id uint) error
	GetAllMenusWithRoles(page, pageSize int) ([]model.Menu, int64, error)
	GetUserMenus(userID uint) ([]model.Menu, error)
	AddMenuPermissions(menuID uint, permissions []model.Permission) error
	GetMenuPermissions(menuID uint) ([]model.Permission, error)
}

type menuService struct {
	repo repository.MenuRepository
}

func NewMenuService(repo repository.MenuRepository) MenuService {
	return &menuService{repo: repo}
}

func (s *menuService) GetAllMenus(page, pageSize int) ([]model.Menu, int64, error) {
	return s.repo.GetAllMenus(page, pageSize)
}

func (s *menuService) GetMenuByID(id uint) (*model.Menu, error) {
	return s.repo.GetMenuByID(id)
}

func (s *menuService) CreateMenu(req *request.CreateMenuRequest) (*model.Menu, error) {
	menu := &model.Menu{
		Title:         req.Title,
		Path:          req.Path,
		ComponentPath: req.ComponentPath,
		Icon:          req.Icon,
		Sort:          req.Sort,
		ParentID:      req.ParentID,
		Status:        req.Status,
	}
	return s.repo.CreateMenu(menu)
}

func (s *menuService) UpdateMenu(id uint, req *request.UpdateMenuRequest) (*model.Menu, error) {
	menu, err := s.repo.GetMenuByID(id)
	if err != nil {
		return nil, errors.NewNotFoundError("菜单不存在", err)
	}

	menu.Title = req.Title
	menu.Path = req.Path
	menu.ComponentPath = req.ComponentPath
	menu.Icon = req.Icon
	menu.Sort = req.Sort
	menu.ParentID = req.ParentID
	menu.Status = req.Status

	return s.repo.UpdateMenu(menu)
}

func (s *menuService) DeleteMenu(id uint) error {
	if _, err := s.repo.GetMenuByID(id); err != nil {
		return errors.NewNotFoundError("菜单不存在", err)
	}
	return s.repo.DeleteMenu(id)
}

func (s *menuService) GetAllMenusWithRoles(page, pageSize int) ([]model.Menu, int64, error) {
	return s.repo.GetAllWithRoles(page, pageSize)
}

func (s *menuService) GetUserMenus(userID uint) ([]model.Menu, error) {
	return s.repo.GetUserMenus(userID)
}

func (s *menuService) AddMenuPermissions(menuID uint, permissions []model.Permission) error {
	return s.repo.AddMenuPermissions(menuID, permissions)
}

func (s *menuService) GetMenuPermissions(menuID uint) ([]model.Permission, error) {
	return s.repo.GetMenuPermissions(menuID)
}
